-- @Author: baidwwy
-- @Date:   2018-04-11 03:48:53
-- @Last Modified by:   baidwwy
-- @Last Modified time: 2018-08-17 05:56:36
math.pi2 =  math.pi*2
table.unpack = unpack
gge = {}
setmetatable(_G, {__index=gge})
bit = require("bit")
--ffi------------------------------------------------------------------
    ffi = require("ffi")
    local ffi_loaded = {}
    ffi._load = ffi.load
    ffi.load = function (k)
        if not ffi_loaded[k] then ffi_loaded[k] = ffi._load(k) end
        return ffi_loaded[k]
    end
--string------------------------------------------------------------------
    local mt = getmetatable('')
    mt.__index = function(str,i)
        if type(i) == 'number' then
            return string.byte(str,i,i)
        else
            return string[i]
        end
    end
    mt.__newindex = function(str,i,v)
        if type(i)=='number' and type(v)=="number" and i>0 and i<=string.len(str) then
            ffi.cast("int8_t*",str)[i-1] = v
        end
    end
--class------------------------------------------------------------------
    local _CLASS    = {}--保存父类
    local function _Call(t, ... )--免".创建"
        return t.创建(...)
    end
    local function _Create(self,ct,ctor,...)--构造函数
        local r
        for i,v in ipairs(ct["_S\0"]) do
            r = _Create(self,v,_CLASS[ct][v],...)--继承属性
            if r==false then return r end
        end
        if ctor then return ctor(self,...)
        elseif ct.初始化 then return ct.初始化(self,...)
        end
    end
    function class(...)
        local super,sck,sct = {...}
        local ct    = {初始化=false,["_S\0"]=super}--创建的对象
        _CLASS[ct]  = {}--类函数实际保存
        ct.创建   = function(...)
            local ctor = {}
            setmetatable(ctor,{ __index = function (t,k)
                if _CLASS[k] then
                    sck = k;return t--记录要运行的父类
                elseif sck then
                    sct,sck=sck,nil
                    return _CLASS[sct][k]--父函数
                end
                return _CLASS[ct][k]--本身函数
            end})
            return ctor,_Create(ctor,ct,nil,...)--递归所有父类
        end
        if #super > 0 then--继承函数
            for i,v in ipairs(super) do
                assert(_CLASS[v], "父类不正确。",v)
            end
            setmetatable(_CLASS[ct],{__index = function (t,k)
                for i,v in ipairs(super) do
                    local ret = _CLASS[v][k]
                    if ret then return ret end
                end
            end})
        end
        return setmetatable(ct,{__index=_CLASS[ct],__newindex=_CLASS[ct],__call=_Call})
    end
--Class高级类,带有销毁事件,但性能比class低------------------------------------------------------------------
    local function _Destroy(self,c)--析构函数
        if c.销毁 then c.销毁(self) end
        for i=#c["_S\0"],1,-1 do
            _Destroy(self,c["_S\0"][i])
        end
    end
    function Class(...)
        local super,sck,sct = {...}
        local ct    = {初始化=false,销毁=false,["_S\0"]=super}--创建的对象
        _CLASS[ct]  = {}--类函数实际保存
        ct.创建   = function(...)
            local ctor,dtor = {},newproxy(true)--self
            setmetatable(ctor,{ __index = function (t,k)
                if _CLASS[k] then
                    sck = k;return t
                elseif sck then
                    sct,sck=sck,nil
                    return _CLASS[sct][k]
                end
                return _CLASS[ct][k]
            end,__gc=dtor})
            local r = _Create(ctor,ct,nil,...)--递归所有父类
            getmetatable(dtor).__gc = function (t)
                _Destroy(ctor,ct)--递归所有父类
            end
            return r==nil and ctor or r
        end
        if #super > 0 then--继承函数
            for i,v in ipairs(super) do
                assert(type(v) == 'table', "父类不正确。",v)
            end
            setmetatable(_CLASS[ct],{__index = function (t,k)
                for i,v in ipairs(super) do
                    local ret = _CLASS[v][k]
                    if ret then return ret end
                end
            end})
        end
        return setmetatable(ct,{__index=_CLASS[ct],__newindex=_CLASS[ct],__call=_Call})
    end
--=============================================================================================

local errored = {}
local function tracebackex()
    local ret = ""
    local level = 3
    ret = ret .. "stack traceback:\n"
    while true do
        --get stack info
        local info = debug.getinfo(level, "Sln")
        if not info then break end
        if info.what == "C" then                -- C function
            --ret = ret .. string.format("\t[C]: in function '%s'\n", info.name or "")
        elseif info.short_src ~= '[string "GGELUA_MAIN"]'then           -- Lua function
            ret = ret .. string.format("\t%s:%d: in function '%s'\n", info.short_src, info.currentline, info.name or "")
        end
        --get local vars
        local i = 1
        while true do
            local name, value = debug.getlocal(level, i)
            if not name then break end
            if name~='self' and name~='(*temporary)' and name: sub(1,4)~='(for' then
                value =  tostring(value)
                if value:find("\n") then
                    value = value:match("([^\n]+)").." ……"
                end
                ret = ret .. string.format("\t\t%-20s= %s\n", name,value)
            end

            i = i + 1
        end
        level = level + 1
    end
    return ret
end
__gge.traceback = function (msg)
    if not errored[msg] then
        print("-----------------------------------------------------------------")
        if msg then
            print(tostring(msg) .. "--按F4或双击此行可转到错误代码页--")
            print(">>>>>>>>>>>>>>>>>>>>>>>>>以下为错误跟踪<<<<<<<<<<<<<<<<<<<<<<<<<<")
        end
        print(tracebackex())
        print("-----------------------------------------------------------------")
        errored[msg] = true
        if 引擎 and __gge.isgame then
            引擎.关闭()
        end
    end
end
gge.checkggetype = function (v)
    if type(v)=='table' then
        return tostring(v)
    end
end

local _print = print
function print( ... )
    local args = { ... };
    for i=1,table.maxn(args) do
        if type(args[i])=='string' and #args[i]%2 ~= 0 then
            args[i] = args[i]..' '
        elseif args[i] == nil then
            args[i] = "nil"
        end
    end
    args[1] = args[1]==nil and 'nil' or args[1]
    if __gge.isdebug or __gge.isserver then
        _print(unpack(args))
    else
        引擎.写日志(...)
    end
end
